package com.dd.cloud.user.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;

@Slf4j
public class PdfToImgUtil {


    static String PATH = "imgTemp66";

    /**
     * description: 使用url 下载远程文件
     *
     * @param urlPath --- url资源
     * @return void
     * @throws Exception
     * @version v1.0
     * @author w
     * @date 2019年9月3日 下午8:29:01
     */
    public static String getImagBase64(String urlPath) throws Exception {
        String targetDirectory = PATH + File.separator;
        // 解决url中可能有中文情况
        System.out.println("url:" + urlPath);
        URL url = new URL(urlPath);
        HttpURLConnection http = (HttpURLConnection) url.openConnection();
        http.setConnectTimeout(3000);
        // 设置 User-Agent 避免被拦截
        http.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
        String contentType = http.getContentType();
        System.out.println("contentType: " + contentType);
        // 获取文件大小
        long length = http.getContentLengthLong();
        System.out.println("文件大小：" + (length / 1024) + "KB");
        // 获取文件名
        String fileName = getFileName(urlPath);
        File outFile = new File(targetDirectory + fileName);
        String filePath = targetDirectory + fileName;
        System.out.println(filePath);
        if (!outFile.getParentFile().exists()) {
            outFile.getParentFile().mkdirs();
        }
        InputStream inputStream = http.getInputStream();
        byte[] buff = new byte[1024 * 10];
        OutputStream out = new FileOutputStream(new File(targetDirectory, fileName));
        int len;
        int count = 0; // 计数
        while ((len = inputStream.read(buff)) != -1) {
            out.write(buff, 0, len);
            out.flush();
            ++count;
        }
        log.info("count:" + count);
        // 关闭资源
        out.close();
        inputStream.close();
        http.disconnect();
        //生成图片
        String imgPath = pdf2png(filePath, "png", fileName);
        //生成BASE64
        String imageBase64 = imageToBase64(imgPath);
        //删除文件
        delete(targetDirectory);
        return imageBase64;
    }




    /**
     * @param path 图片路径
     * @return
     * @Descriptionmap 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
     * @author temdy
     * @Date 2015-01-26
     */
    public static String imageToBase64(String path) {// 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(path);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);// 返回Base64编码过的字节数组字符串
    }


    /**
     * 转换全部的pdf
     *
     * @param type 图片类型
     */
    public static String pdf2png(String pdfPath, String type, String fileName) throws UnsupportedEncodingException {
        // 将pdf装图片 并且自定义图片得格式大小
        File file = new File(pdfPath);
        String[] strArray = fileName.split("\\.");
        String imgPath = "";
        if (StringUtils.isNotBlank(strArray[0])) {
            imgPath = PATH + File.separator + strArray[0] + "." + type;
            log.info(imgPath);
        }
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = 0; i < pageCount; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
                ImageIO.write(image, type, new File(imgPath));
            }
            doc.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imgPath;
    }


    /**
     * 自由确定起始页和终止页
     *
     * @param fileAddress  文件地址
     * @param filename     pdf文件名
     * @param indexOfStart 开始页  开始转换的页码，从0开始
     * @param indexOfEnd   结束页  停止转换的页码，-1为全部
     * @param type         图片类型
     */
    public static void pdf2png(String fileAddress, String filename, int indexOfStart, int indexOfEnd, String type) {
        // 将pdf装图片 并且自定义图片得格式大小
        File file = new File(fileAddress + "\\" + filename + ".pdf");
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = indexOfStart; i < indexOfEnd; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
                ImageIO.write(image, type, new File(fileAddress + "\\" + filename + "_" + (i + 1) + "." + type));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * description: 获取文件名
     *
     * @param urlPath
     * @return String
     * @throws UnsupportedEncodingException
     * @version v1.0
     * @author w
     * @date 2019年9月3日 下午8:25:55
     */
    private static String getFileName(String urlPath) throws UnsupportedEncodingException {
        String fileName = null;
//        if(null != headerField) {
//            String decode = URLDecoder.decode(headerField, "UTF-8");
//            fileName = decode.split(";")[1].split("=")[1].replaceAll("\"", "");
//            System.out.println("文件名是： "+ fileName);
//        }
        if (null == fileName) {
            // 尝试从url中获取文件名
            String[] arr = urlPath.split("/");
            fileName = arr[arr.length - 1];
            log.info("url中获取文件名：" + fileName);
        }
        return fileName;
    }


    /**
     * 删除文件，可以是文件或文件夹
     *
     * @param fileName：要删除的文件名
     * @return 删除成功返回true，否则返回false
     */
    public static boolean delete(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            log.info("删除文件失败:" + fileName + "不存在！");
            return false;
        } else {
            if (file.isFile()) {
                return deleteFile(fileName);
            } else {
                return deleteDirectory(fileName);
            }
        }
    }

    /**
     * 删除单个文件
     *
     * @param fileName：要删除的文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                log.info("删除单个文件" + fileName + "成功！");
                return true;
            } else {
                log.info("删除单个文件" + fileName + "失败！");
                return false;
            }
        } else {
            log.info("删除单个文件失败：" + fileName + "不存在！");
            return false;
        }
    }

    /**
     * 删除目录及目录下的文件
     *
     * @param dir：要删除的目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String dir) {
        // 如果dir不以文件分隔符结尾，自动添加文件分隔符
        if (!dir.endsWith(File.separator)) {
            dir = dir + File.separator;
        }
        File dirFile = new File(dir);
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            log.info("删除目录失败：" + dir + "不存在！");
            return false;
        }
        boolean flag = true;
        // 删除文件夹中的所有文件包括子目录
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
            // 删除子目录
            else if (files[i].isDirectory()) {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }
        if (!flag) {
            log.info("删除目录失败！");
            return false;
        }
        // 删除当前目录
        if (dirFile.delete()) {
            log.info("删除目录" + dir + "成功！");
            return true;
        } else {
            return false;
        }
    }
}
